//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Common Core Extensions
//===============================================================================

using System;
using System.IO;
using System.ComponentModel;

namespace EntLibContrib.Common.Configuration.Design
{
	/// <summary>
	/// Abstract file based resource name converter.
	/// </summary>
	internal abstract class FileResourceNameConverter : TypeConverter
	{
		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="FileResourceNameConverter"/> class.
		/// </summary>
		public FileResourceNameConverter()
		{
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Gets the properties.
		/// </summary>
		/// <param name="context">The context.</param>
		/// <param name="value">The value.</param>
		/// <param name="filter">The filter.</param>
		/// <returns>a collection of property descriptors</returns>
		public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context,	object value, Attribute[] filter)
		{
			return TypeDescriptor.GetProperties(value, filter);
		}

		/// <summary>
		/// Returns whether this object supports properties, using the
		/// specified context.
		/// </summary>
		/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
		/// <returns>
		/// 	<see langword="true "/>if <see cref="M:System.ComponentModel.TypeConverter.GetProperties(System.Object)"/> should be called to find the properties
		/// of this object; otherwise, <see langword="false"/>.
		/// </returns>
		public override bool GetPropertiesSupported(ITypeDescriptorContext context) 
		{
			return true;
		}

		/// <summary>
		/// Returns
		/// whether this converter can convert an object of the given type to the type of this converter, using
		/// the specified context.
		/// </summary>
		/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
		/// <param name="sourceType">A <see cref="T:System.Type"/> that represents the type you want to convert from.</param>
		/// <returns>
		/// 	<see langword="true "/>if this converter can perform the conversion; otherwise,
		/// <see langword="false"/>.
		/// </returns>
		public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
		{
			if (sourceType == typeof(string))
				return true;

			return base.CanConvertFrom(context, sourceType);
		}

		/// <summary>
		/// Returns whether this converter
		/// can convert the object to the specified type, using the specified context.
		/// </summary>
		/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
		/// <param name="destinationType">A <see cref="T:System.Type"/> that represents the type you want to convert to.</param>
		/// <returns>
		/// 	<see langword="true "/>if this converter can perform the conversion; otherwise,
		/// <see langword="false"/>.
		/// </returns>
		public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
		{
			if (destinationType == typeof(string))
				return true;

			return base.CanConvertTo (context, destinationType);
		}

		/// <summary>
		/// Converts the given value object
		/// to the specified type, using the specified context and culture information.
		/// </summary>
		/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
		/// <param name="culture">A <see cref="T:System.Globalization.CultureInfo"/> object. If <see langword="null"/> is passed, the current culture is assumed.</param>
		/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
		/// <param name="destinationType">The <see cref="T:System.Type"/> to convert the <paramref name="value"/> parameter to.</param>
		/// <returns>
		/// An <see cref="T:System.Object"/> that represents
		/// the converted value.
		/// </returns>
		/// <exception cref="T:System.ArgumentNullException">The <paramref name="destinationType"/> parameter is <see langword="null"/>.</exception>
		/// <exception cref="T:System.NotSupportedException">The conversion could not be performed.</exception>
		public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
		{
			if (destinationType == typeof(string))
			{
				FileResourceName fileResourceName = (FileResourceName)value;
				if (String.IsNullOrEmpty(fileResourceName.PathName))
					return null;
				else
					return Path.Combine(fileResourceName.PathName, fileResourceName.BaseName + FindFileResourceNameExtension());
			}
			return base.ConvertTo (context, culture, value, destinationType);
		}

		/// <summary>
		/// Finds the file resource name extension.
		/// </summary>
		/// <returns>extension name with separator</returns>
		public abstract string FindFileResourceNameExtension();
		#endregion
	}
}
